﻿
using HBase;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace hconnect {
    public class ModbusTcpConnect :SocketZtTaskConnect {
        protected short transaction_id = 0;
        protected byte _identifier;
        protected override bool init() {
            base.init();
            String ipStr = ip.Split('.')[3];
            this._identifier = Convert.ToByte(int.Parse(ipStr));
            return true;
        }
        public byte[] Receive(int len) {
            byte[] array = ReadTelex(len);
            ModbusUtil.CheckErr(array ,transaction_id ,_identifier);
            return array;
        }
        public byte[] Receive() {
            byte[] array = ReadTelex(256);
            ModbusUtil.CheckErr(array ,transaction_id ,_identifier);
            return array;
        }

       
        public byte[] ZeroingRegisters(ushort len) {//拼接报文并发送
          
            bool flag2 = len > 123;
            if( flag2 ) {
                return null;
            }
            ushort message_len = ( ushort ) (7 + len * 2);
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(16);
            list.AddRange(ModbusUtil.GetBytes(0));
            list.AddRange(ModbusUtil.GetBytes(len));
            list.Add(( byte ) (len * 2));
            for( int i = 0;i < ( int ) len;i++ ) {
                list.AddRange(ModbusUtil.GetBytes(0));
            }
            return write(list);
        }
        public byte[] ReadCoils(ushort start_address ,ushort len) {
            byte[] first = ModbusUtil.BuildMBAPHeader(this._identifier ,len);
            byte[] second = ModbusUtil.BulidReadCoilsTelex(start_address ,len);
            byte[] result;
            byte[] buffer = first.Concat(second).ToArray<byte>();
            bool flag2 = this.Send(buffer);
            if( flag2 ) {

                result = this.Receive();
            } else {
                result = null;
            }
            return result;
        }
        public byte[] ReadDiscreteInputs(ushort start_address ,ushort len) {
            byte[] result;
            bool flag2 = len > 2000;
            if( flag2 ) {
                result = null;
            } else {
                ushort message_len = 6;
                byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
                List<byte> list = new List<byte>();
                list.AddRange(collection);
                list.Add(2);
                list.AddRange(ModbusUtil.GetBytes(start_address));
                list.AddRange(ModbusUtil.GetBytes(len));
                bool flag3 = this.Send(list.ToArray());
                if( flag3 ) {

                    result = this.Receive();
                } else {
                    throw new Exception(ip + "+" + port + "网络异常");
                    
                }
            }
            return result;
        }
        public byte[] ReadHoldingRegisters(ushort start_address ,ushort len) {
            byte[] buffer = ModbusUtil.readHoldingRegistersHeader(this._identifier ,start_address ,len);
            bool flag2 = this.Send(buffer);
            if( flag2 ) {

                return this.Receive(len * 2 + 9);
            }
            return null;
        }
        public byte[] ReadInputRegisters(ushort start_address ,ushort len) {
            byte[] result = null;
            if( len > 125 ) {
                return null;
            }
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(4);
            list.AddRange(ModbusUtil.GetBytes(start_address));
            list.AddRange(ModbusUtil.GetBytes(len));
            bool flag3 = this.Send(list.ToArray());
            if( flag3 ) {

                result = this.Receive();
            }
            return result;
        }
        public byte[] WriteSingleCoil(ushort address ,bool value) {
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(5);
            list.AddRange(ModbusUtil.GetBytes(address));
            list.AddRange(ModbusUtil.GetBytes(value ? 65280 : 0));
     
            return write(list);
        }
        public byte[] WriteSingleRegisters(ushort address ,ushort value) {
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(6);
            list.AddRange(ModbusUtil.GetBytes(( short ) address));
            list.AddRange(ModbusUtil.GetBytes(( short ) value));
            return write(list);
        }
        public byte[] WriteMultipleCoils(ushort start_address ,bool[] values) {
    
            bool flag3 = values.Length > 1968;
            if( flag3 ) {
                return null;
            }
            byte b = ( byte ) (values.Length / 8 + ((values.Length % 8 == 0) ? 0 : 1));
            ushort message_len = ( ushort ) (7 + b);
            byte[] array = new byte[( int ) b];
            BitArray bitArray = new BitArray(values);
            bitArray.CopyTo(array ,0);
            byte[] array2 = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.Add(15);
            list.AddRange(ModbusUtil.GetBytes(start_address));
            list.AddRange(ModbusUtil.GetBytes(( ushort ) values.Length));
            list.Add(b);
            list.AddRange(array);
            return write(list);
        }
        public byte[] MaskWriteRegister(ushort address ,ushort and_mask ,ushort or_mask) {
            ushort message_len = 8;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(22);
            list.AddRange(ModbusUtil.GetBytes(( short ) address));
            list.AddRange(ModbusUtil.GetBytes(and_mask));
            list.AddRange(ModbusUtil.GetBytes(or_mask));
            
            return write(list);
        }
        public byte[] WriteMultipleRegisters(ushort start_address ,ushort[] values) {
           
            bool flag3 = values.Length > 123;
            if( flag3 ) {
                return null;
            }
            ushort message_len = ( ushort ) (7 + values.Length * 2);
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(16);
            list.AddRange(ModbusUtil.GetBytes(( short ) start_address));
            list.AddRange(ModbusUtil.GetBytes(( short ) values.Length));
            list.Add(( byte ) (values.Length * 2));
            for( int i = 0;i < values.Length;i++ ) {
                list.AddRange(ModbusUtil.GetBytes(values[i]));
            }
            return write(list);
        }

        public byte[] WriteRegisters(ushort start_address ,byte[] b) {
          
            bool flag3 = b.Length > 123;
            if( flag3 ) {
                return null;
            }
            ushort message_len = ( ushort ) (7 + b.Length);
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(16);
            list.AddRange(ModbusUtil.GetBytes(( short ) start_address));
            list.AddRange(ModbusUtil.GetBytes(( short ) (b.Length / 2)));
            list.Add(( byte ) b.Length);
            list.AddRange(b);
            return write(list);
        }
        public byte[] ReadWriteMultipleRegisters(ushort read_start_address ,ushort read_len ,ushort write_start_address ,ushort[] write_values) {
            byte[] result = null;
            bool flag3 = read_len > 125 || write_values.Length > 121;
            if( flag3 ) {
                return null;
            }
            ushort message_len = ( ushort ) (11 + write_values.Length * 2);
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(23);
            list.AddRange(ModbusUtil.GetBytes(read_start_address));
            list.AddRange(ModbusUtil.GetBytes(write_start_address));
            list.AddRange(ModbusUtil.GetBytes(( ushort ) write_values.Length));
            list.Add(( byte ) (write_values.Length * 2));
            for( int i = 0;i < write_values.Length;i++ ) {
                list.AddRange(ModbusUtil.GetBytes(write_values[i]));
            }
            bool flag4 = this.Send(list.ToArray());
            if( flag4 ) {

                result = this.Receive();
            }
            return result;
        }

        private byte[] write(List<byte> list) {
            byte[] result = null;
            bool flag4 = this.Send(list.ToArray());
            if (flag4) {
                byte[] array = ReadTelex(256);
                for (int i=0;i< array.Length;i++) {

                    if (array[i] != list[i]) {
                        throw new Exception("modbus send error");
                    }
                }
             
            }
               return result;
        }
    }
}
